package com.zzyl.job;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.CacheConstants;
import com.zzyl.entity.AlertRule;
import com.zzyl.mapper.AlarmRuleMapper;
import com.zzyl.service.AlarmRuleService;
import com.zzyl.vo.DeviceDataVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据监控的定时任务
 * spring task定时任务的编码流程：
 *  1. 导入jar包 但是如果你是springboot的项目默认就已导入
 *  2. 在启动引入类上添加@EnableScheduleing
 *  3. 编码一个任务类 类里面编写一个任务方法 方法上添加@Scheduled 注解并使用cron表示式设置执行的周期
 *  cron表示式:
 *      秒 分 时 日 月 周
 *  日和周是冲突的，所以一般只这只一个 一般都是设置日 放弃周(19好是星期五 星期五是19号)
 *  放弃：？
 *  任意时间: *
 *
 */
@Component
public class AlertJob {

    @Autowired
    private AlarmRuleMapper alarmRuleMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AlarmRuleService alarmRuleService;

    @Scheduled(cron = "* * * * * ?")
    public void alertJob(){
        //1. 查询所有的规则 如果没有规则 则结束这次校验
        List<AlertRule> alertRuleList = alarmRuleMapper.queryAlarm(null,null,null);
        if(CollUtil.isEmpty(alertRuleList)){
            return;
        }

        //2. 如果有规则 则查询redis中所有设备缓存的数据(json)
        List<Object> values = stringRedisTemplate.opsForHash().values(CacheConstants.IOT_DEVICE_LAST_DATA_KEY);
        //3. 判断json是否都为空 则结束这次校验
        if(CollUtil.isEmpty(values)){
            return;
        }

        //4. 如果有数据 则把json转换为vo对象
        List<DeviceDataVo> allDataList = new ArrayList<>();
        values.stream().forEach(val -> {
            String json = (String)val;//千万不要使用val.toString() (String)null
            //List<DeviceDataVo> deviceDataVos = JSONUtil.toList(json, DeviceDataVo.class);
            allDataList.addAll(JSONUtil.toList(json, DeviceDataVo.class));
        });

        //5. 遍历每一天数据进行数据的校验
        allDataList.stream().forEach(vo -> {
            alarmRuleService.alertFilter(vo);
        });
    }
}
